﻿#define _CRT_SECURE_NO_WARNINGS


//结构体
/*
* 
		struct tag
		{
			member-list;
		}variable-list;
		例如描述一个学生
		struct Stu
		{
			char name[20];//名字
			int age;//年龄
			char sex[5];//性别
		};
*/
#include <stdio.h>
#include <stddef.h>
//#pragma 这个预处理指令，可以改变编译器的默认对⻬数
//#pragma pack(4)//设置默认对⻬数为4
//#pragma pack()//还原为默认
//int main()
//{
//	//结构体自引用
//	typedef struct Node
//	{
//		int data;
//		struct Node* next;
//	}Node;//重定义数据类型 struct Node -> Node
//	struct Node_1
//	{
//		int data;
//		struct Node* next;
//	}Node_1 = {0};//定义struct Node_1类型的变量Node_1
//	//并且struct Node和struct Node_1在编译器看来并不等效
//	//匿名结构体尽量少使用（即省略tag）
//	/*
//	* 	
//	struct
//	{
//		int data;
//		struct Node* next;
//	}Node_2;
//	*/
//	/*
//	* 	
//	typedef struct Node
//	{
//		int data;
//		struct Node next;
//	};//这种不对因为结构体里面定义相同的结构体会导致永远不知道他的大小
//	*/
//
//	//内存对齐
//	//offsetof用于计算结构体/联合体的成员的偏移量（相对）结构体/联合体的起始地址
//	struct S1
//	{
//		char c1;
//		int i;
//		char c2;
//	};
//	printf("sizeof(struct S1)=%d byte\n", sizeof(struct S1));
//	printf("offsetof(struct S1, c1)=%d byte\n", offsetof(struct S1, c1));
//	printf("offsetof(struct S1, i)=%d byte\n", offsetof(struct S1, i));
//	printf("offsetof(struct S1, c2)=%d byte\n\n", offsetof(struct S1, c2));
//	struct S2
//	{
//		char c1;
//		char c2;
//		int i;
//	};
//	printf("sizeof(struct S2)=%d byte\n", sizeof(struct S2));
//	printf("offsetof(struct S2, c1)=%d byte\n", offsetof(struct S2, c1));
//	printf("offsetof(struct S2, c2)=%d byte\n\n", offsetof(struct S2, c2));
//	printf("offsetof(struct S2, i)=%d byte\n", offsetof(struct S2, i));
//	
//	struct S3
//	{
//		double d;
//		char c;
//		int i;
//	};
//	printf("sizeof(struct S3)=%d byte\n", sizeof(struct S3));
//	
//	struct S4
//	{
//		char c1;
//		struct S3 s3;
//		double d;
//	};
//	printf("sizeof(struct S4)=%d byte\n", sizeof(struct S4));
//	
//	return 0;
//}



struct S
{
	int data[1000];
	int num;
};
struct S s = { {1,2,3,4}, 1000 };
//结构体传参
void print1(struct S s)
{
	printf("%d\n", s.num);
}
//结构体地址传参
void print2(struct S* ps)
{
	printf("%d\n", ps->num);
}
int main()
{
	print1(s); //传结构体
	print2(&s); //传地址
	return 0;
}

//上⾯的 print1 和 print2 函数哪个好些？
//答案是：⾸选print2函数。
//原因：
//函数传参的时候，参数是需要压栈，会有时间和空间上的系统开销。
//如果传递⼀个结构体对象的时候，结构体过⼤，参数压栈的的系统开销⽐较⼤，所以会导致性能的下
//降。